package com.csf.controller.interceptor;

import com.csf.entity.LoginTicket;
import com.csf.entity.SessionReplace;
import com.csf.entity.User;
import com.csf.service.UserService;
import com.csf.util.CookieUitl;
import org.apache.kafka.common.security.auth.AuthenticationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

@Component
public class LoginUserInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    @Autowired
    private SessionReplace replace;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//首先从浏览器端获取cookie，查看登陆凭证
        String ticket = CookieUitl.getVals(request, "ticket");
//如果有登陆凭证，则获取Loginticket中的值
        LoginTicket loginTicket = userService.findLoginTicket(ticket);
//        获取之后，通过该值获取登录用户的所有信息
//        检查凭证是否有效（凭证状态和是否超出保存时长）
        if (loginTicket != null && loginTicket.getStatus()==0 && loginTicket.getExpired().after(new Date())){
            User localUser = userService.findUserById(loginTicket.getUserId());
            //将用户信息放入线程中（代替session）
            replace.setUser(localUser);
//构建用户认证的结果，便于security授权（用户访问服务器的时候会进行拦截查看登陆凭证，如果凭证有效
// ，则说明用户是登陆状态，然后查看用户的权限认证，以便确认它是否是否有权限访问当前页面）
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
                    localUser, localUser.getPassword(), userService.getAuthorities(localUser.getId())
            );
            SecurityContextHolder.setContext(new SecurityContextImpl(token));
        }

        //        不做拦截
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//从线程中获取user的信息，放入model中
        User user = replace.getUser();
        if (modelAndView != null && user != null){
             modelAndView.addObject("user",user);
        }
    }

//    当所有流程执行完毕
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        SecurityContextHolder.clearContext();
        replace.Clear();
    }
}
